// $ANTLR 2.7.6 (2005-12-22): "RelatedItemsTreeParser.g" -> "QueryLanguageTreeParser.cs"$

using System;
using antlr;
using antlr.collections;
using antlr.collections.impl;
using Lucene.Net.Index;
using Lucene.Net.Search;
using SearchTools.Factories;
using SearchTools.Providers;

namespace SearchTools.QueryParser
{
    // Generate header specific to the tree-parser CSharp file
    
    public class QueryLanguageTreeParser : TreeParser
    {
        public const int EOF = 1;
        public const int NULL_TREE_LOOKAHEAD = 3;
        public const int CLAUSE = 4;
        public const int TERM = 5;
        public const int PREFIX = 6;
        public const int BOOST = 7;
        public const int FUZZY = 8;
        public const int RANGE = 9;
        public const int QUALIFIEDTERM = 10;
        public const int UNQUALIFIEDTERM = 11;
        public const int INJECTMETA = 12;
        public const int INJECTHISTORY = 13;
        public const int HISTORYBIAS = 14;
        public const int REF = 15;
        public const int AND = 16;
        public const int OR = 17;
        public const int PLUS = 18;
        public const int MINUS = 19;
        public const int OPEN_PAREN = 20;
        public const int CLOSE_PAREN = 21;
        public const int CARET = 22;
        public const int TILDE = 23;
        public const int HASH = 24;
        public const int LITERAL_injectmeta = 25;
        public const int COMMA = 26;
        public const int IDENT = 27;
        public const int LITERAL_historybias = 28;
        public const int LITERAL_injecthistory = 29;
        public const int COLON = 30;
        public const int STRING_LITERAL = 31;
        public const int NUM_INT = 32;
        public const int NUM_DOUBLE = 33;
        public const int NUM_FLOAT = 34;
        public const int OPEN_SQUARE = 35;
        public const int TO = 36;
        public const int CLOSE_SQUARE = 37;
        public const int NOT = 38;
        public const int DOLLAR = 39;
        public const int WS = 40;
        public const int CHAR_LITERAL = 41;
        public const int ESC = 42;
        public const int HEX_DIGIT = 43;
        public const int EXPONENT = 44;
        public const int FLOAT_SUFFIX = 45;
        public const int NUM_LONG = 46;
        public const int DOT = 47;

        public static readonly string[] tokenNames_ = new string[]
            {
                @"""<0>""",
                @"""EOF""",
                @"""<2>""",
                @"""NULL_TREE_LOOKAHEAD""",
                @"""CLAUSE""",
                @"""TERM""",
                @"""PREFIX""",
                @"""BOOST""",
                @"""FUZZY""",
                @"""RANGE""",
                @"""QUALIFIEDTERM""",
                @"""UNQUALIFIEDTERM""",
                @"""INJECTMETA""",
                @"""INJECTHISTORY""",
                @"""HISTORYBIAS""",
                @"""REF""",
                @"""AND""",
                @"""OR""",
                @"""PLUS""",
                @"""MINUS""",
                @"""OPEN_PAREN""",
                @"""CLOSE_PAREN""",
                @"""CARET""",
                @"""TILDE""",
                @"""HASH""",
                @"""injectmeta""",
                @"""COMMA""",
                @"""IDENT""",
                @"""historybias""",
                @"""injecthistory""",
                @"""COLON""",
                @"""STRING_LITERAL""",
                @"""NUM_INT""",
                @"""NUM_DOUBLE""",
                @"""NUM_FLOAT""",
                @"""OPEN_SQUARE""",
                @"""TO""",
                @"""CLOSE_SQUARE""",
                @"""NOT""",
                @"""DOLLAR""",
                @"""WS""",
                @"""CHAR_LITERAL""",
                @"""ESC""",
                @"""HEX_DIGIT""",
                @"""EXPONENT""",
                @"""FLOAT_SUFFIX""",
                @"""NUM_LONG""",
                @"""DOT"""
            };

        public static readonly BitSet tokenSet_0_ = new BitSet(mk_tokenSet_0_());

        public QueryLanguageTreeParser()
        {
            tokenNames = tokenNames_;
        }

        public Query query(AST _t) //throws RecognitionException
        {
            Query q;

            AST query_AST_in = (AST) _t;

            q = new BooleanQuery();
            Query c = null;
            Query sq = null;


            try
            {
                // for error handling
                {
                    // ( ... )*
                    for (;;)
                    {
                        if (_t == null)
                            _t = ASTNULL;
                        if ((tokenSet_0_.member(_t.Type)))
                        {
                            {
                                c = clause(_t);
                                _t = retTree_;
                            }

                            ((BooleanQuery) q).Add(c, BooleanClause.Occur.SHOULD);
                        }
                        else
                        {
                            goto _loop4_breakloop;
                        }
                    }
                    _loop4_breakloop:
                    ;
                } // ( ... )*
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public Query clause(AST _t) //throws RecognitionException
        {
            Query q;

            AST clause_AST_in = (AST) _t;

            Query c = null;
            Query expr = null;
            Query bc = null;
            Query lhs = null;
            Query rhs = null;
            Query bcl = null;
            q = null;
            double b = 0;


            try
            {
                // for error handling
                {
                    if (null == _t)
                        _t = ASTNULL;
                    switch (_t.Type)
                    {
                        case PLUS:
                            {
                                AST __t7 = _t;
                                AST tmp1_AST_in = _t;
                                match(_t, PLUS);
                                _t = _t.getFirstChild();
                                c = clause(_t);
                                _t = retTree_;
                                _t = __t7;
                                _t = _t.getNextSibling();

                                //Must have 
                                q = new BooleanQuery();
                                ((BooleanQuery) q).Add(c, BooleanClause.Occur.MUST);

                                break;
                            }
                        case MINUS:
                            {
                                AST __t8 = _t;
                                AST tmp2_AST_in = _t;
                                match(_t, MINUS);
                                _t = _t.getFirstChild();
                                c = clause(_t);
                                _t = retTree_;
                                _t = __t8;
                                _t = _t.getNextSibling();

                                //Must not have
                                q = new BooleanQuery();
                                ((BooleanQuery) q).Add(c, BooleanClause.Occur.MUST_NOT);

                                break;
                            }
                        case CLAUSE:
                            {
                                AST __t9 = _t;
                                AST tmp3_AST_in = _t;
                                match(_t, CLAUSE);
                                _t = _t.getFirstChild();
                                c = clause(_t);
                                _t = retTree_;
                                _t = __t9;
                                _t = _t.getNextSibling();

                                q = c;

                                break;
                            }
                        case RANGE:
                        case QUALIFIEDTERM:
                        case UNQUALIFIEDTERM:
                        case INJECTMETA:
                        case INJECTHISTORY:
                        case HISTORYBIAS:
                            {
                                {
                                    expr = expression(_t);
                                    _t = retTree_;
                                }

                                //Pass through expression query
                                q = expr;

                                break;
                            }
                        case AND:
                            {
                                AST __t11 = _t;
                                AST tmp4_AST_in = _t;
                                match(_t, AND);
                                _t = _t.getFirstChild();
                                lhs = clause(_t);
                                _t = retTree_;
                                rhs = clause(_t);
                                _t = retTree_;
                                _t = __t11;
                                _t = _t.getNextSibling();

                                //Boolean and
                                q = new BooleanQuery();
                                ((BooleanQuery) q).Add(lhs, BooleanClause.Occur.MUST);
                                ((BooleanQuery) q).Add(rhs, BooleanClause.Occur.MUST);

                                break;
                            }
                        case OR:
                            {
                                AST __t12 = _t;
                                AST tmp5_AST_in = _t;
                                match(_t, OR);
                                _t = _t.getFirstChild();
                                lhs = clause(_t);
                                _t = retTree_;
                                rhs = clause(_t);
                                _t = retTree_;
                                _t = __t12;
                                _t = _t.getNextSibling();

                                //Boolean or
                                q = new BooleanQuery();
                                ((BooleanQuery) q).Add(lhs, BooleanClause.Occur.SHOULD);
                                ((BooleanQuery) q).Add(rhs, BooleanClause.Occur.SHOULD);

                                break;
                            }
                        case BOOST:
                            {
                                AST __t13 = _t;
                                AST tmp6_AST_in = _t;
                                match(_t, BOOST);
                                _t = _t.getFirstChild();
                                bcl = clause(_t);
                                _t = retTree_;
                                b = boost(_t);
                                _t = retTree_;
                                _t = __t13;
                                _t = _t.getNextSibling();

                                q = bcl;
                                q.SetBoost((float) b);

                                break;
                            }
                        default:
                            {
                                throw new NoViableAltException(_t);
                            }
                    }
                }
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public Query expression(AST _t) //throws RecognitionException
        {
            Query q;

            AST expression_AST_in = (AST) _t;
            AST f = null;

            Query func = null;
            Query t = null;
            q = null;


            try
            {
                // for error handling
                if (null == _t)
                    _t = ASTNULL;
                switch (_t.Type)
                {
                    case INJECTMETA:
                    case INJECTHISTORY:
                    case HISTORYBIAS:
                        {
                            {
                                func = function(_t);
                                _t = retTree_;
                            }

                            //Pass through function query
                            q = func;

                            break;
                        }
                    case RANGE:
                    case QUALIFIEDTERM:
                    case UNQUALIFIEDTERM:
                        {
                            {
                                {
                                    t = term(_t);
                                    _t = retTree_;
                                }

                                //Pass through term query
                                q = t;

                                {
                                    if (null == _t)
                                        _t = ASTNULL;
                                    switch (_t.Type)
                                    {
                                        case FUZZY:
                                            {
                                                AST __t19 = _t;
                                                AST tmp7_AST_in = _t;
                                                match(_t, FUZZY);
                                                _t = _t.getFirstChild();
                                                f = _t == ASTNULL ? null : _t;
                                                num(_t);
                                                _t = retTree_;
                                                _t = __t19;
                                                _t = _t.getNextSibling();

                                                //Fuzzy query, extract terms from q and convert to fuzzy,
                                                //we can assume this is a term query
                                                FuzzyQuery fuzzyQuery = new FuzzyQuery(((TermQuery) t).GetTerm(),
                                                                                       (float)
                                                                                       Convert.ToDouble(f.getText()), 0);
                                                q = fuzzyQuery;

                                                break;
                                            }
                                        case 3:
                                        case CLAUSE:
                                        case BOOST:
                                        case RANGE:
                                        case QUALIFIEDTERM:
                                        case UNQUALIFIEDTERM:
                                        case INJECTMETA:
                                        case INJECTHISTORY:
                                        case HISTORYBIAS:
                                        case AND:
                                        case OR:
                                        case PLUS:
                                        case MINUS:
                                        case NUM_INT:
                                        case NUM_DOUBLE:
                                        case NUM_FLOAT:
                                            {
                                                break;
                                            }
                                        default:
                                            {
                                                throw new NoViableAltException(_t);
                                            }
                                    }
                                }
                            }
                            break;
                        }
                    default:
                        {
                            throw new NoViableAltException(_t);
                        }
                }
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public double boost(AST _t) //throws RecognitionException
        {
            double r;

            AST boost_AST_in = (AST) _t;
            AST n = null;

            r = 0;


            try
            {
                // for error handling
                {
                    n = _t == ASTNULL ? null : _t;
                    num(_t);
                    _t = retTree_;
                }

                r = Convert.ToDouble(n.getText());
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return r;
        }

        public Query function(AST _t) //throws RecognitionException
        {
            Query q;

            AST function_AST_in = (AST) _t;

            q = null;
            Query meta = null;
            Query hist = null;


            try
            {
                // for error handling
                if (null == _t)
                    _t = ASTNULL;
                switch (_t.Type)
                {
                    case INJECTMETA:
                        {
                            {
                                meta = metaInjection(_t);
                                _t = retTree_;
                            }

                            //Pass through link
                            q = meta;

                            break;
                        }
                    case INJECTHISTORY:
                        {
                            {
                                hist = historyInjection(_t);
                                _t = retTree_;
                            }

                            //Pass through history
                            q = hist;

                            break;
                        }
                    case HISTORYBIAS:
                        {
                            {
                                hist = historyBias(_t);
                                _t = retTree_;
                            }

                            //Pass through history bias
                            q = hist;

                            break;
                        }
                    default:
                        {
                            throw new NoViableAltException(_t);
                        }
                }
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public Query term(AST _t) //throws RecognitionException
        {
            Query q;

            AST term_AST_in = (AST) _t;

            q = null;
            Query qt = null; //Qualified term query
            Query u = null; //Unqualified term query
            Query r = null; //Range query
            Query t = null;
            double f;


            try
            {
                // for error handling
                if (null == _t)
                    _t = ASTNULL;
                switch (_t.Type)
                {
                    case QUALIFIEDTERM:
                        {
                            qt = qualifiedTerm(_t);
                            _t = retTree_;

                            //Pass through qualified term query
                            q = qt;

                            break;
                        }
                    case UNQUALIFIEDTERM:
                        {
                            u = unqualifiedTerm(_t);
                            _t = retTree_;

                            //Pass through unqualified term query
                            q = u;

                            break;
                        }
                    case RANGE:
                        {
                            r = range(_t);
                            _t = retTree_;

                            //Pass through range query
                            q = r;

                            break;
                        }
                    default:
                        {
                            throw new NoViableAltException(_t);
                        }
                }
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public void num(AST _t) //throws RecognitionException
        {
            AST num_AST_in = (AST) _t;

            try
            {
                // for error handling
                if (null == _t)
                    _t = ASTNULL;
                switch (_t.Type)
                {
                    case NUM_INT:
                        {
                            AST tmp8_AST_in = _t;
                            match(_t, NUM_INT);
                            _t = _t.getNextSibling();
                            break;
                        }
                    case NUM_DOUBLE:
                        {
                            AST tmp9_AST_in = _t;
                            match(_t, NUM_DOUBLE);
                            _t = _t.getNextSibling();
                            break;
                        }
                    case NUM_FLOAT:
                        {
                            AST tmp10_AST_in = _t;
                            match(_t, NUM_FLOAT);
                            _t = _t.getNextSibling();
                            break;
                        }
                    default:
                        {
                            throw new NoViableAltException(_t);
                        }
                }
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
        }

        public Query metaInjection(AST _t) //throws RecognitionException
        {
            Query q;

            AST metaInjection_AST_in = (AST) _t;
            AST field = null;

            ProviderReference source;
            q = null;


            try
            {
                // for error handling
                AST __t27 = _t;
                AST tmp11_AST_in = _t;
                match(_t, INJECTMETA);
                _t = _t.getFirstChild();
                source = providerReference(_t);
                _t = retTree_;
                field = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
                _t = __t27;
                _t = _t.getNextSibling();

                q = LinkFactory.Create(source, field.getText());
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public Query historyInjection(AST _t) //throws RecognitionException
        {
            Query q;

            AST historyInjection_AST_in = (AST) _t;
            AST field = null;

            ProviderReference source;
            q = null;


            try
            {
                // for error handling
                AST __t29 = _t;
                AST tmp12_AST_in = _t;
                match(_t, INJECTHISTORY);
                _t = _t.getFirstChild();
                source = providerReference(_t);
                _t = retTree_;
                field = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
                _t = __t29;
                _t = _t.getNextSibling();
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public Query historyBias(AST _t) //throws RecognitionException
        {
            Query q;

            AST historyBias_AST_in = (AST) _t;

            ProviderReference source;
            Query sub;
            q = null;


            try
            {
                // for error handling
                AST __t31 = _t;
                AST tmp13_AST_in = _t;
                match(_t, HISTORYBIAS);
                _t = _t.getFirstChild();
                source = providerReference(_t);
                _t = retTree_;
                sub = query(_t);
                _t = retTree_;
                _t = __t31;
                _t = _t.getNextSibling();
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public ProviderReference providerReference(AST _t) //throws RecognitionException
        {
            ProviderReference r;

            AST providerReference_AST_in = (AST) _t;
            AST provider = null;
            AST key = null;

            r = new ProviderReference();


            try
            {
                // for error handling
                AST __t33 = _t;
                AST tmp14_AST_in = _t;
                match(_t, REF);
                _t = _t.getFirstChild();
                provider = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
                key = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
                _t = __t33;
                _t = _t.getNextSibling();

                r = new ProviderReference(provider.getText(), key.getText());
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return r;
        }

        public Query qualifiedTerm(AST _t) //throws RecognitionException
        {
            Query q;

            AST qualifiedTerm_AST_in = (AST) _t;
            AST f = null;
            AST l = null;
            AST i = null;

            q = null;


            try
            {
                // for error handling
                AST __t36 = _t;
                AST tmp15_AST_in = _t;
                match(_t, QUALIFIEDTERM);
                _t = _t.getFirstChild();
                f = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
                {
                    if (null == _t)
                        _t = ASTNULL;
                    switch (_t.Type)
                    {
                        case STRING_LITERAL:
                            {
                                l = _t;
                                match(_t, STRING_LITERAL);
                                _t = _t.getNextSibling();

                                //PhraseQuery, field specified
                                q = new PhraseQuery();

                                ((PhraseQuery) q).Add(new Term(f.getText(), l.getText()));

                                break;
                            }
                        case IDENT:
                            {
                                i = _t;
                                match(_t, IDENT);
                                _t = _t.getNextSibling();

                                //Term query, field specified
                                q = new TermQuery(new Term(f.getText(), i.getText()));

                                break;
                            }
                        default:
                            {
                                throw new NoViableAltException(_t);
                            }
                    }
                }
                _t = __t36;
                _t = _t.getNextSibling();
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public Query unqualifiedTerm(AST _t) //throws RecognitionException
        {
            Query q;

            AST unqualifiedTerm_AST_in = (AST) _t;
            AST l = null;
            AST i = null;

            q = null;


            try
            {
                // for error handling
                AST __t39 = _t;
                AST tmp16_AST_in = _t;
                match(_t, UNQUALIFIEDTERM);
                _t = _t.getFirstChild();
                {
                    if (null == _t)
                        _t = ASTNULL;
                    switch (_t.Type)
                    {
                        case STRING_LITERAL:
                            {
                                l = _t;
                                match(_t, STRING_LITERAL);
                                _t = _t.getNextSibling();

                                //Phrase query, no field
                                q = new PhraseQuery();

                                ((PhraseQuery) q).Add(new Term("", l.getText()), 5);

                                break;
                            }
                        case IDENT:
                            {
                                i = _t;
                                match(_t, IDENT);
                                _t = _t.getNextSibling();

                                //Term query, no field
                                q = new TermQuery(new Term("", i.getText()));

                                break;
                            }
                        default:
                            {
                                throw new NoViableAltException(_t);
                            }
                    }
                }
                _t = __t39;
                _t = _t.getNextSibling();
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return q;
        }

        public RangeQuery range(AST _t) //throws RecognitionException
        {
            RangeQuery r;

            AST range_AST_in = (AST) _t;
            AST f = null;
            AST from = null;
            AST to = null;

            r = null;


            try
            {
                // for error handling
                AST __t44 = _t;
                AST tmp17_AST_in = _t;
                match(_t, RANGE);
                _t = _t.getFirstChild();
                f = _t == ASTNULL ? null : _t;
                fieldname(_t);
                _t = retTree_;
                from = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
                to = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
                _t = __t44;
                _t = _t.getNextSibling();

                r = new RangeQuery(new Term(f.getText(), from.getText()),
                                   new Term(f.getText(), to.getText()), true);
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
            return r;
        }

        public void fieldname(AST _t) //throws RecognitionException
        {
            AST fieldname_AST_in = (AST) _t;

            try
            {
                // for error handling
                AST tmp18_AST_in = _t;
                match(_t, IDENT);
                _t = _t.getNextSibling();
            }
            catch (RecognitionException ex)
            {
                reportError(ex);
                if (null != _t)
                {
                    _t = _t.getNextSibling();
                }
            }
            retTree_ = _t;
        }


        private static long[] mk_tokenSet_0_()
        {
            long[] data = {1015440L, 0L};
            return data;
        }
    }
}